package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //1.准备大key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        //2.准备小key
        String hashKey = skuId.toString();

        BoundHashOperations<String,String, CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        if(boundHashOperations.hasKey(hashKey)){
            //3.购物车添加已经存在的商品
            CartInfo cartInfo = boundHashOperations.get(hashKey);
            Integer thresHold = cartInfo.getSkuNum() + skuNum;
            skuNum = thresHold > 99 ? 99 :  thresHold;
            cartInfo.setSkuNum(skuNum);
            cartInfo.setUpdateTime(new Date());
            boundHashOperations.put(hashKey,cartInfo);
        }else{
            //首次添加，需要判断购物车数据量是否超过50种商品，不允许超过50
            Long size = boundHashOperations.size(); //  hk的数量
            if(++size > 50){
                throw new ServiceException("商品种类不能超过50");
            }
            //4.首次添加购物车商品
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);

            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if(R.FAIL == productSkuResult.getCode()){
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setCartPrice(productSku.getSalePrice()); //当商品销售价格变动，和购物车价格不一样，那么，购物车列表页面会有价格变动的提示
            cartInfo.setSkuPrice(productSku.getSalePrice());
            cartInfo.setSkuNum(1);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setCreateTime(new Date());
            //cartInfo.setIsChecked(1); // 默认 商品被勾选
            boundHashOperations.put(hashKey,cartInfo);
        }

    }


    private String getCartKey(Long userId) {
        return "user:cart:"+ userId;
    }


    @Override
    public List<CartInfo> getCartList() {
        //1.准备大key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();

        //2.将购物车数据进行排序：按照添加时间倒序
        List<CartInfo> orderedCartInfoList = cartInfoList.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).toList();

        //3.更新购物车商品的最新价格，这样购物车列表页面会有价格变动提示
        List<Long> skuIdLsit = orderedCartInfoList.stream().map((cartInfo) -> cartInfo.getSkuId()).toList();
        R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdLsit, SecurityConstants.INNER);
        if(R.FAIL == skuPriceListResult.getCode()){
            throw new ServiceException(skuPriceListResult.getMsg());
        }
        List<SkuPrice> skuPriceList = skuPriceListResult.getData();
        //将List数据转为Map数据结构
        Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream()
                .collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
        for (CartInfo cartInfo : orderedCartInfoList) {
            //将数据库最新价格更新到内存CartInfo对象中。注意：并没有更新redis中的数据。
            cartInfo.setSkuPrice(skuIdToSalePriceMap.get(cartInfo.getSkuId()));
            ///////////boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
        }

        return orderedCartInfoList;
    }


    @Override
    public void deleteCart(Long skuId) {
        //1.准备大key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        //2.准备hashkey
        String hashKey = skuId.toString();

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        if(boundHashOperations.hasKey(hashKey)){
            boundHashOperations.delete(hashKey);
        }
    }


    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //1.准备大key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        //2.准备hashkey
        String hashKey = skuId.toString();

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        if(boundHashOperations.hasKey(hashKey)){
            CartInfo cartInfo = boundHashOperations.get(hashKey);
            cartInfo.setIsChecked(isChecked);
            boundHashOperations.put(hashKey,cartInfo);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        //1.准备大key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if(!CollectionUtils.isEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
                cartInfo.setIsChecked(isChecked); //每一个商品勾选状态都和总的勾选状态一致
                boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
            }
        }
    }

    @Override
    public void clearCart() {
        //1.准备大key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        if(redisTemplate.hasKey(cartKey)){
            redisTemplate.delete(cartKey);
        }
    }


    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        //1.准备大key
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if(!CollectionUtils.isEmpty(cartInfoList)){
            //过滤出勾选的商品
            return cartInfoList.stream().filter((cartInfo) -> cartInfo.getIsChecked() == 1).toList();
        }
        return new ArrayList<>();
    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        //1.准备大key
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if(!CollectionUtils.isEmpty(cartInfoList)){

            List<Long> skuIdList = cartInfoList.stream().map((cartInfo) -> cartInfo.getSkuId()).toList();
            R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
            if(R.FAIL == skuPriceListResult.getCode()){
                throw new ServiceException(skuPriceListResult.getMsg());
            }
            List<SkuPrice> skuPriceList = skuPriceListResult.getData();
            Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
            for (CartInfo cartInfo : cartInfoList) {
                if(cartInfo.getIsChecked().intValue() == 1){ //打钩的，就是购买的
                    BigDecimal salePrice = skuIdToSalePriceMap.get(cartInfo.getSkuId());
                    cartInfo.setCartPrice(salePrice);
                    cartInfo.setSkuPrice(salePrice);
                    cartInfo.setUpdateTime(new Date());
                    boundHashOperations.put(cartInfo.getSkuId().toString(),cartInfo);
                }
            }
        }
        return true;
    }


    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        //1.准备大key
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);

        List<CartInfo> cartInfoList = boundHashOperations.values();

        if(!CollectionUtils.isEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
                if(cartInfo.getIsChecked().intValue() == 1){ //打钩的商品
                    boundHashOperations.delete(cartInfo.getSkuId().toString());
                }
            }
        }
        return true;
    }
}